package com.multipleimageselect.activities;

import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.asman.base.lib.utils.StatusBarUtil;
import com.jph.takephoto.R;
import com.multipleimageselect.adapters.CustomAlbumSelectAdapter;
import com.multipleimageselect.helpers.Constants;
import com.multipleimageselect.models.Album;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;

/**
 * Created by Darshan on 4/14/2015.
 */
public class AlbumSelectActivity extends HelperActivity {
    private ArrayList<Album> albums;

    private TextView errorDisplay;

    private ProgressBar progressBar;
    private RecyclerView recyclerView;
    private CustomAlbumSelectAdapter adapter;

    private ContentObserver observer;
    private Handler handler;
    private Thread thread;

    private boolean videoEnable = false;//默认不可选择视频

    private final String[] projection = new String[]{
            MediaStore.Images.Media.BUCKET_ID,
            MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
            MediaStore.Images.Media.DATA};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_album_select);
//        setView(findViewById(R.id.layout_album_select));
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBarWithBack(toolbar, R.drawable.ic_back, v -> finish());
        toolbar.setTitle(R.string.album_view);
        Intent intent = getIntent();
        if (intent == null) {
            finish();
            return;
        }
        Constants.limit = intent.getIntExtra(Constants.INTENT_EXTRA_LIMIT, Constants.DEFAULT_LIMIT);
        videoEnable = intent.getBooleanExtra(Constants.INTENT_VIDEO_ENABLE, false);

        errorDisplay = findViewById(R.id.text_view_error);
        errorDisplay.setVisibility(View.INVISIBLE);

        progressBar = findViewById(R.id.progress_bar_album_select);
        recyclerView = findViewById(R.id.grid_view_album_select);
        recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
        StatusBarUtil.INSTANCE.setDarkModel(this);
        StatusBarUtil.INSTANCE.setColor(this, Color.parseColor("#ffffff"));
    }

    static class MyHandler extends Handler {
        WeakReference<AlbumSelectActivity> weakReference;

        MyHandler(AlbumSelectActivity activity) {
            weakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.PERMISSION_GRANTED:
                    weakReference.get().loadAlbums();
                    break;
                case Constants.FETCH_STARTED:
                    weakReference.get().progressBar.setVisibility(View.VISIBLE);
                    weakReference.get().recyclerView.setVisibility(View.INVISIBLE);
                    break;
                case Constants.FETCH_COMPLETED:
                    if (weakReference.get().adapter == null) {
                        weakReference.get().adapter = new CustomAlbumSelectAdapter(weakReference.get().albums);
                        weakReference.get().recyclerView.setAdapter(weakReference.get().adapter);
                        weakReference.get().progressBar.setVisibility(View.INVISIBLE);
                        weakReference.get().recyclerView.setVisibility(View.VISIBLE);
                    }
                    break;
                case Constants.ERROR:
                    weakReference.get().progressBar.setVisibility(View.INVISIBLE);
                    weakReference.get().errorDisplay.setVisibility(View.VISIBLE);
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        handler = new MyHandler(this);

        observer = new ContentObserver(handler) {
            @Override
            public void onChange(boolean selfChange, Uri uri) {
                loadAlbums();
            }
        };
        getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, observer);
        checkPermission();
    }

    @Override
    protected void onStop() {
        super.onStop();

        stopThread();

        getContentResolver().unregisterContentObserver(observer);
        observer = null;

        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
            handler = null;
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        setResult(RESULT_CANCELED);
        finish();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == Constants.REQUEST_CODE
                && resultCode == RESULT_OK
                && data != null) {
            setResult(RESULT_OK, data);
            finish();
        }
    }

    private MenuItem item_video;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_album, menu);
        item_video = menu.findItem(R.id.item_video);
        item_video.setVisible(videoEnable);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int i = item.getItemId();
        if (i == android.R.id.home) {
            onBackPressed();
            return true;
        } else if (i == R.id.item_video) {
            //显示所有视频
            Intent intent = new Intent(this, VideoSelectActivity.class);
            intent.putExtra(Constants.INTENT_EXTRA_ALBUM, "所有视频");
            startActivityForResult(intent, Constants.REQUEST_CODE);
            return true;
        } else {
            return false;
        }
    }

    private void loadAlbums() {
        startThread(new AlbumLoaderRunnable());
    }

    private class AlbumLoaderRunnable implements Runnable {
        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

            if (adapter == null) {
                sendMessage(Constants.FETCH_STARTED);
            }

            Cursor cursor = getApplicationContext().getContentResolver()
                    .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
                            null, null, MediaStore.Images.Media.DATE_ADDED);

            if (cursor == null) {
                sendMessage(Constants.ERROR);
                return;
            }

            ArrayList<Album> temp = new ArrayList<>();
            HashSet<Long> albumSet = new HashSet<>();
            File file;
            if (cursor.moveToLast()) {
                do {
                    if (Thread.interrupted()) {
                        return;
                    }

                    long albumId = cursor.getLong(cursor.getColumnIndex(projection[0]));
                    String album = cursor.getString(cursor.getColumnIndex(projection[1]));
                    String image = cursor.getString(cursor.getColumnIndex(projection[2]));

                    //fixme RN会导致根目录有缓存上传的图片，导致根目录图片重复出现，这里做过滤处理
                    if (!"0".equals(album)) {
                        if (!albumSet.contains(albumId)) {
                        /*
                        It may happen that some image file paths are still present in cache,
                        though image file does not exist. These last as long as media
                        scanner is not run again. To avoid get such image file paths, check
                        if image file exists.
                         */
                            file = new File(image);
                            if (file.length() > 0) {
                                if (file.exists()) {
                                    temp.add(new Album(album, image));
                                    albumSet.add(albumId);
                                }
                            } else {
                                file.delete();
                            }
                        }
                    }
                } while (cursor.moveToPrevious());
            }
            cursor.close();

            if (albums == null) {
                albums = new ArrayList<>();
            }
            albums.clear();
            albums.addAll(temp);

            sendMessage(Constants.FETCH_COMPLETED);
        }
    }

    private void startThread(Runnable runnable) {
        stopThread();
        thread = new Thread(runnable);
        thread.start();
    }

    private void stopThread() {
        if (thread == null || !thread.isAlive()) {
            return;
        }

        thread.interrupt();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void sendMessage(int what) {
        if (handler == null) {
            return;
        }

        Message message = handler.obtainMessage();
        message.what = what;
        message.sendToTarget();
    }

    @Override
    protected void permissionGranted() {
        Message message = handler.obtainMessage();
        message.what = Constants.PERMISSION_GRANTED;
        message.sendToTarget();
    }

    @Override
    protected void hideViews() {
        progressBar.setVisibility(View.INVISIBLE);
        recyclerView.setVisibility(View.INVISIBLE);
    }
}
